﻿// -----------------------------------------------------------------------
// <copyright file="RemixApi.cs" company="Spardo, LLC">
// Copyright (c) 2011 SPardo, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a 
// copy of this software and associated documentation files (the "Software"), 
// to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, 
// and/or sell copies of the Software, and to permit persons to whom the 
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included 
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
// </copyright>
// -----------------------------------------------------------------------

namespace BBYOpen.Linq
{
    using System;
    using System.IO;
    using System.Net;
    using System.Runtime.Serialization.Json;
    using BBYOpen.Linq.Common;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    internal class RemixApi
    {
        public static TResult ApiCall<TResult>(string url)
        {
            var request = HttpWebRequest.Create(url);
            var response = request.GetResponse();
            string json = GetJsonResponse(response);

            if (typeof(TResult).Name == "IEnumerable`1")
            {
                var genericType = TypeSystem.GetElementType(typeof(TResult));
                var name = TypeSystem.GetDataContractName(genericType);

                json = json.Replace(string.Format("\"{0}\":", name)
                    , "\"resultList\":");

                Type pageableType = typeof(Pageable<>).MakeGenericType(genericType);

                return Deserialize<TResult>(json, pageableType);
            }
            else
            {
                return Deserialize<TResult>(json, typeof(TResult));
            }
        }

        private static string GetJsonResponse(WebResponse response)
        {
            string output = string.Empty;

            using (var stream = response.GetResponseStream())
            {
                using (var reader = new StreamReader(stream))
                {
                    output = reader.ReadToEnd();
                }
            }

            return output;
        }

        private static TResult Deserialize<TResult>(string json, Type type)
        {
            TResult output = default(TResult);

            using (var stream = new MemoryStream())
            {
                var writer = new StreamWriter(stream);
                writer.Write(json);
                writer.Flush();

                stream.Position = 0;
                
                var serializer = new DataContractJsonSerializer(type);
                output = (TResult)serializer.ReadObject(stream);
            }

            return output;
        }
    }
}
